package com.next

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes = 'username')
@ToString(includes = 'username', includeNames = true, includePackage = false)
class User implements Serializable
{
    private static final long serialVersionUID = 1

    transient springSecurityService

    String username
    String password

    String fullName

    boolean enabled = true
    boolean accountExpired = false
    boolean accountLocked = false
    boolean passwordExpired = false

    String cellphone
    String email

    Department department
    // Position position
    City city

    String externalId

    String appSessionId

    String avatarUrl

    SecurityProfile securityProfile

    String verificationCode

    Date lastPasswordModifiedDate

    Boolean loginBySms = false

    Boolean fixedIp = false

    String ip

    Territory territory

    Boolean dynamicMenu = false

    User reportTo
    Integer reportLevel = 1

    Boolean shareActivityToSupervisor = true
    Boolean shareAccountToSupervisor = true
    Boolean shareContactToSupervisor = true
    Boolean shareLeadToSupervisor = true
    Boolean shareOpportunityToSupervisor = true
    Boolean shareCampaignToSupervisor = true
    Boolean shareIssueToSupervisor = true
    Boolean shareAssetToSupervisor = true

    Date createdDate = new Date()
    Date modifiedDate = new Date()

    User createBy
    User modifyBy

    User(String username, String password)
    {
        this()
        this.username = username
        this.password = password
    }

    Set<Role> getAuthorities()
    {
        UserRole.findAllByUser(this)*.role
    }

    def beforeInsert()
    {
        encodePassword()

        if (reportTo)
        {
            reportLevel = reportTo.reportLevel + 1
        }

        def username = springSecurityService?.getPrincipal()?.username
        createBy = User.findByUsername(username)
    }

    def beforeUpdate()
    {
        if (isDirty('password'))
        {
            encodePassword()
        }

        if (reportTo)
        {
            reportLevel = reportTo.reportLevel + 1
        }

        modifiedDate = new Date()
        def username = springSecurityService?.getPrincipal()?.username
        modifyBy = User.findByUsername(username)
    }

    protected void encodePassword()
    {
        password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
    }

    static transients = ['springSecurityService']

    static constraints = {
        password blank: false, password: true, minSize: 6, maxSize: 256
        //        , matches: "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\\S+\$).{8,}\$"
        username blank: false, unique: true
        // fullName blank: true, nullable: true
        department blank: true, nullable: true
        // position blank: true, nullable: true

        cellphone size: 11..11 //, blank: true, nullable: true //, unique: true
        email nullable: true, blank: true, email: true
        city blank: true, nullable: true

        externalId blank: true, nullable: true //, unique: true

        appSessionId blank: true, nullable: true //, unique: true

        avatarUrl nullable: true, blank: true, maxSize: 256

        securityProfile blank: true, nullable: true

        //        reportTo blank: true, nullable: true
        verificationCode blank: true, nullable: true, maxSize: 16

        ip blank: true, nullable: true, maxSize: 64

        lastPasswordModifiedDate blank: true, nullable: true

        territory blank: true, nullable: true
        dynamicMenu blank: true, nullable: true

        reportTo blank: true, nullable: true
        reportLevel blank: true, nullable: true

        shareActivityToSupervisor blank: true, nullable: true
        shareAccountToSupervisor blank: true, nullable: true
        shareContactToSupervisor blank: true, nullable: true
        shareLeadToSupervisor blank: true, nullable: true
        shareOpportunityToSupervisor blank: true, nullable: true
        shareCampaignToSupervisor blank: true, nullable: true
        shareIssueToSupervisor blank: true, nullable: true
        shareAssetToSupervisor blank: true, nullable: true

        createBy nullable: true, blank: true
        modifyBy nullable: true, blank: true
        createdDate nullable: true, blank: true
        modifiedDate nullable: true, blank: true
    }

    static mapping = {
        table 'login_user'
        password column: '`password`'
        // shareOpportunityToSupervisor column: 'share_oppt_to_supervisor'
    }

    String toString()
    {
        String alias

        if (department)
        {
            alias = "${department} - ${fullName}"
        }
        else
        {
            alias = fullName
        }

        alias
    }
}
